//
//  ClientNetworkCenter.m
//  Karaoke
//
//  Created by Ka Leung Ke on 11-10-17.
//  Copyright 2011年 __MyCompanyName__. All rights reserved.
//

#import "ClientNetworkCenter.h"
#import "ServerNetworkCenter.h"
@implementation ClientNetworkCenter

@synthesize isConnect, isStopRetry;
static ClientNetworkCenter * _sharedInstance;

+ (ClientNetworkCenter *) sharedInstance
{
    if (!_sharedInstance)
    {
        _sharedInstance = [[ClientNetworkCenter alloc] init];
    }

    return _sharedInstance;
}

- (id) init
{
    self = [super init];

    if (self)
    {
        isConnect = NO;
        isStopRetry = YES;
        retryTimer = nil;
        // Initialization code here.
        receiveData = [[NSMutableData alloc] init];
        dataOffset = 0;
        encGBK = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
    }

    return self;
}

- (BOOL) getConnected
{
    return [mainSocket isConnected];
}

- (void) connectToServerWithIp:(NSString *)tempIp:(int)tempPort
{
    lastConnectIp = [tempIp copy];
    lastConnectPort = tempPort;

    if ([ServerNetworkCenter sharedInstance].isConnect == YES)
    {
        [[ServerNetworkCenter sharedInstance] disconnectToServer];
    }

    if (isConnect == YES)
    {
        [self disconnectToServer];
    }

    [receiveData setLength:0];
    dataOffset = 0;

    mainSocket = [[AsyncSocket alloc] initWithDelegate:self];

    NSError * err = nil;

    NSLog(@"trying to connect server ip: %@, port: %i", tempIp, tempPort);

    if ([mainSocket connectToHost:tempIp onPort:tempPort withTimeout:3.0f error:&err])
    {}
    else
    {
        NSLog(@"Fail to develop connection");
    }
}

- (void) stopRetry
{
    if (retryTimer != nil)
    {
        [retryTimer invalidate];
        retryTimer = nil;
    }

    isStopRetry = YES;
}

- (void) retryConnectLastConnection
{
    [self connectToServerWithIp:lastConnectIp:lastConnectPort];
    retryTimer = nil;
}

- (void) sentMsgAskForAddSongWithCode:(NSString *)tempSongCode
{
    [self sentMsg:pcAddSong:tempSongCode, nil];
}

- (void) sentMsgAskForDelSongWithCode:(NSString *)tempSongCode
{
    [self sentMsg:pcDeleteSong:tempSongCode, nil];
}

- (void) sentMsgAskForPushSongWithCode:(NSString *)tempSongCode
{
    [self sentMsg:pcPrioritySong:tempSongCode, @"0", nil];
}

- (void) sentMsgAskForCutSong
{
    [self sendMsg:pcStop];
}

- (void) sentMsgAskForChangeToOriginalMusic
{
    //    NSLog(@"sent msg ask for sentMsgAskForChangeToOriginalMusic");

    [self sendMsg:pcYC];
}

- (void) sentMsgAskForChangeToSideMusic
{
    //    NSLog(@"sent msg ask for sentMsgAskForChangeToSideMusic");
    [self sendMsg:pcBC];
}

- (void) sentMsgAskForMute
{
    //    NSLog(@"sent msg ask for sentMsgAskForMute");
    [self sendMsg:pcSetMute];
}

- (void) sentMsgAskForPauseOrPlay
{
    //    NSLog(@"sent msg ask for sentMsgAskForPause");
    [self sendMsg:pcPauseOrPay];
}

- (void) sentMsgAskForReplay
{
    //    NSLog(@"sent msg ask for sentMsgAskForReplay");
    [self sendMsg:pcReplay];
}

- (void) sentMsgAskForBillList
{
    //    NSLog(@"sent msg ask for sentMsgAskForBillList");
    [self sentMsg:pcGetPlayQueue:@"0", @"0", nil];
}

- (void) sentMsgAskForChangeVol:(int)tempVol // 0 - 100
{
    //    NSLog(@"sent msg ask for sentMsgAskForCancelMute");

    [self sentMsg:pcVolume:@"0",@"1",[NSString stringWithFormat:@"%d", tempVol], @"0", nil];
}

- (void) disconnectToServer
{
    [mainSocket disconnect];
}

- (void) sentMsg:(NSString *)tempMsg
{
    NSData * data = [[[NSData alloc] initWithData:[tempMsg dataUsingEncoding:encGBK]] autorelease];

    NSMutableData * buf = [[NSMutableData alloc] initWithData:
        [[NSString stringWithFormat:@"%0.6i", [data length] + 1 + 6] dataUsingEncoding:encGBK]];

    [buf appendData:data];

    UInt8 tempCRCChar = [self getCRC:buf.bytes:buf.length];

    //    NSLog(@"gen CRC %c", tempCRCChar);
    [buf appendBytes:&tempCRCChar length:1];

    //    NSLog(@"sent out msg: %@ and data: %@", tempFinalString, tempFinalData);
    [mainSocket writeData:buf withTimeout:5 tag:0];
    [buf release];
}

- (void) sendMsg:(int)cmd
{
    [self sentMsg:cmd:nil];
}

- (void) sentMsg:(int)cmd:(NSString *)para, ...
    {
    NSMutableString * temp = [NSMutableString stringWithFormat:@"\r\n%d\r\n", cmd];

    if (para)
    {
        [temp appendFormat:@"%@\r\n", para];
        id      arg;
        va_list argList;
        va_start(argList, para);

        while ((arg = va_arg(argList, id)))
        {
            [temp appendFormat:@"%@\r\n", arg];
        }

        va_end(argList);
    }

    [self sentMsg:temp];
}

- (void) sendMsg:(int)cmd:(NSArray *)para
{
    NSString * temp = [NSString stringWithFormat:@"\r\n%d\r\n%@", cmd, [para componentsJoinedByString:@"\r\n"]];

    [self sentMsg:temp];
}

- (void) onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag
{
    //    NSLog(@"Did write the data");
}

- (void) onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
    [receiveData appendData:data];
    //    NSLog(@"receive data length: %d", data.length);

    while (receiveData.length > 0)
    {
        int tempPacketSize = [[[NSString alloc] initWithData:[receiveData subdataWithRange:NSMakeRange(0, 6)] encoding:NSUTF8StringEncoding]  autorelease].intValue;

        if (tempPacketSize > receiveData.length)
        {
            NSLog(@"数据接收不完整，等待内容");
            break;
        }

        if ([self checkIfVaildMsg:[receiveData subdataWithRange:NSMakeRange(0, tempPacketSize)]])
        {
            NSString * msg = [[[NSString alloc] initWithData:[receiveData subdataWithRange:NSMakeRange(0, tempPacketSize - 1)] encoding:encGBK] autorelease];

            NSLog(@"clientNetWork have receive msg:%@", msg);
            [[DataCenter sharedInstance] forwardNoticeCode:@"tcpMsg" detail:msg];

            NSArray * tmpArray = [msg componentsSeparatedByString:@"\r\n"];
            int       cmd = [[tmpArray objectAtIndex:1] intValue];

            if ((cmd == pcUpdatePlayQueue) || (cmd == pcGetPlayQueue))
            {
                if (cmd == pcUpdatePlayQueue)
                {
                    [self performSelectorInBackground:@selector(updateBillListThread:) withObject:tmpArray];
                }
                else
                {
                    [self performSelectorInBackground:@selector(updateBillListThread2:) withObject:tmpArray];
                }
            }
        }
        else
        {
            NSLog(@"error wrong key again length: %i and data: %@", [data length], data);
        }

        //删除已经处理过的内容
        if (receiveData.length - tempPacketSize == 0)
        {
            receiveData.length = 0;
        }
        else
        {
            [receiveData replaceBytesInRange:NSMakeRange(0, tempPacketSize) withBytes:NULL length:0];
        }
    }

    [mainSocket readDataWithTimeout:-1 tag:0];
}

- (void) updateBillListThread:(NSArray *)tmpArray
{
    NSAutoreleasePool * apool = [[NSAutoreleasePool alloc] init];

    /*  请求:
     *   返回:
     *   DataCount:Integer;//返回数据记录数
     *   (
     *   SongCode:String; //歌曲代码
     *   SongName:String;//歌曲名称
     *   Singer1:String;//歌星1
     *   Singer2:String;//歌星2
     *   Language:String;//语种
     *   HitCount:Integer;//点播率
     *   )
     */

    NSMutableArray * tempArray = [[NSMutableArray array] retain];

    for (int i = 3; i < [tmpArray count] - 1; i += 6)
    {
        SongObject * obj = [[[SongObject alloc] init] autorelease]; // [[DataCenter sharedInstance] getSongObjectWithSongId:[tmpArray objectAtIndex:i]];

        obj.songCode = [tmpArray objectAtIndex:i];
        obj.songName = [tmpArray objectAtIndex:i + 1];
        obj.singerName1 = [tmpArray objectAtIndex:i + 2];
        obj.singerName2 = [tmpArray objectAtIndex:i + 3];

        [tempArray addObject:obj];
    }

    if ([DataCenter sharedInstance].currentBillListArray != nil)
    {
        [[DataCenter sharedInstance].currentBillListArray release];
        [DataCenter sharedInstance].currentBillListArray = nil;
    }

    [DataCenter sharedInstance].currentBillListArray = tempArray;

    [self performSelectorOnMainThread:@selector(forwardBillListUpdateMsg) withObject:nil waitUntilDone:YES];
    [apool release];
}

- (void) updateBillListThread2:(NSArray *)tmpArray
{
    NSAutoreleasePool * apool = [[NSAutoreleasePool alloc] init];

    /*  请求:
     *   PageSize:Integer; //每页显示数量 0:获取全部记录
     *   CurPage:Integer; //当前页面，当PageSize=0时，该项无效。
     *   返回:
     *   CurPage:Integer;//当前页面
     *   PageCount:Integer;//总页数
     *   DataCount:Integer;//返回数据记录数
     *   (
     *   SongCode:String; //歌曲代码
     *   SongName:String;//歌曲名称
     *   Singer1:String;//歌星1
     *   Singer2:String;//歌星2
     *   Language:String;//语种
     *   HitCount:Integer;//点播率
     *   )
     */

    NSMutableArray * tempArray = [[NSMutableArray array] retain];

    for (int i = 5; i < [tmpArray count] - 1; i += 6)
    {
        SongObject * obj = [[[SongObject alloc] init] autorelease]; // [[DataCenter sharedInstance] getSongObjectWithSongId:[tmpArray objectAtIndex:i]];

        obj.songCode = [tmpArray objectAtIndex:i];
        obj.songName = [tmpArray objectAtIndex:i + 1];
        obj.singerName1 = [tmpArray objectAtIndex:i + 2];
        obj.singerName2 = [tmpArray objectAtIndex:i + 3];

        [tempArray addObject:obj];
    }

    if ([DataCenter sharedInstance].currentBillListArray != nil)
    {
        [[DataCenter sharedInstance].currentBillListArray release];
        [DataCenter sharedInstance].currentBillListArray = nil;
    }

    [DataCenter sharedInstance].currentBillListArray = tempArray;

    [self performSelectorOnMainThread:@selector(forwardBillListUpdateMsg) withObject:nil waitUntilDone:YES];
    [apool release];
}

- (void) forwardBillListUpdateMsg
{
    [[DataCenter sharedInstance] forwardNoticeCode:@"sysMsg" detail:@"billListUpdate"];
}

- (void) onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
    NSLog(@"did connect to server");
    [[DataCenter sharedInstance] forwardNoticeCode:@"sysMsg" detail:@"clientConnected"];
    [mainSocket readDataWithTimeout:-1 tag:0];
    isStopRetry = NO;
}

- (void) onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err
{}

- (void) onSocketDidDisconnect:(AsyncSocket *)sock
{
    NSLog(@"did disconnect already");
    [[DataCenter sharedInstance] forwardNoticeCode:@"sysMsg" detail:@"clientDidDisconnect"];
    mainSocket = nil;
    isConnect = NO;

    if (isStopRetry == NO)
    {
        retryTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(retryConnectLastConnection) userInfo:nil repeats:NO];
    }
}

- (BOOL) checkIfVaildMsg:(NSData *)tempData
{
    const unsigned char * buf = tempData.bytes;
    UInt8                 tempCRCOriginalChar = buf[tempData.length - 1];
    //    UInt8 *tempCRCOriginalChar = (UInt8 *)[[tempData subdataWithRange:NSMakeRange([tempData length] - 1, 1)] bytes];

    //    UInt8 tempCRCChar = [self getCRC:[tempData subdataWithRange:NSMakeRange(0, [tempData length] - 1)]];
    UInt8 tempCRCChar = [self getCRC:buf:tempData.length - 1];

    if (tempCRCChar == tempCRCOriginalChar)
    {
        //        NSLog(@"CRC corrent");
        return YES;
    }

    return NO;
}

- (UInt8) getCRC:(const unsigned char *)buf:(int)len
{
    //    const unsigned char *buf = [data bytes];

    UInt8 crc = 0;

    //    int len = data.length;
    for (int j = 0; j < len; j++)
    {
        crc ^= buf[j];

        for (int i = 0; i < 8; i++)
        {
            if (crc & 0x01)
            {
                crc = (crc >> 1)^0x8C;
            }
            else
                crc >>= 1;
        }
    }

    return crc;
}

@end